(function($, undefined) {
	
$.widget("ui.table", $.ui.mouse, {
	
	options: {
		menu: null,
		
		isBlur: true
	},
	
	drag: {
		row_sort: 1,
		multi_select: 2
	},
	
	_create: function() {
		var $s = this, con = $s.element;
		
		// remove left border in first column
		$s._initFirstTdBorder();
		
		// init edit input
		$s._initEditInput();
		
		// init click tr event and click td event
		$s._initClickEvent();
		
		// init context menu
		$s._initContextMenu();
		
		// init drag dotted select area
		$s.line_area = $("<div style='display: none;position: absolute;border: 1px dotted #999;background: transparent;'></div>");
		con.append($s.line_area);
		
		$(document.body).bind("click", function() { if($s.options.isBlur)  $s._blurInput(true);  $s.options.isBlur = true; });
		
		$s._mouseInit();
	},
	
	getRow: function() {
		return $("tr.tr-selected", this.element);
	},
	
	addKnow: function() {
		var $s = this, tab = $s.element;
		
		var html = "<tr isEdit='Y' isNode='Y'>";
		html += "<td style='border-left: 0;' class='sn'>" + $("tr", tab).size() + "</td>";
		html += "<td></td>";
		html += "<td><div style='font-weight: bold;'></div></td>";
		html += "<td></td>";
		html += "</tr>";
		
		var $tr = $(html).bind("click", function(e) {
			$("tr", tab).removeClass("tr-selected");
			$(this).addClass("tr-selected");
			e.stopPropagation();
		});
		
		$("td:eq(2)", $tr).bind("click", function() { $s._initTdClick($(this)); });
		
		// if has a selected row, append new row after it
		var $selTr = $("tr.tr-selected", tab);
		$selTr.size() > 0 ? $selTr.after($tr) : tab.append($tr);
		
		// focus name column
		$s.options.isBlur = false;
		$s._initTdClick($("td:eq(2)", $tr.click()));
	},
	
	levelUp: function() {
		var $s = this, tab = $s.element, $trs = $s.getRow();
		if($trs.size() == 0)  return;
		
		var $tr = $trs.eq(0), $pTrs = $tr.prevAll("tr[isNode='Y']"), $pTr;
		
		$pTrs.each(function() {
			if((parseInt($(this).attr("level")) + 1) < parseInt($tr.attr("level"))) { $pTr = $(this);  return false; }
		});
		
		var l = parseInt($tr.attr("level")), pl = (!$pTr || $pTr.size() == 0) ? 0 : parseInt($pTr.attr("level"));
		if(l <= pl)  return;
		
		$trs.each(function() {
			// reset level
			var level = parseInt($(this).attr("level")) - 1;
			$(this).attr("level", level);
			
			// reset padding
			var $d = $("td:eq(2) div", this);
			$d.css("padding-left", (level * 18 + 5) + "px");
			
			// set parent node
			$(this).attr("isEdit", "Y").attr("parentId", level == 0 ? "" : $pTr.attr("id"));
		});
		
		if(!$("#saveBtn").attr("disabled") || $("#saveBtn").attr("disabled") == "disabled")  $("#saveBtn").attr("disabled", false);
	},
	
	levelDown: function() {
		var $s = this, tab = $s.element, $trs = $s.getRow();
		if($trs.size() == 0)  return;
		
		var $tr = $trs.eq(0), $pTr = $tr.prevAll("tr[isNode='Y']").eq(0);
		if($pTr.size() == 0)  return;
		
		var l = parseInt($tr.attr("level")), pl = parseInt($pTr.attr("level"));
		if(l > pl)  return;
		
		$trs.each(function() {
			// reset level
			var level = parseInt($(this).attr("level")) + 1;
			$(this).attr("level", level);
			
			// reset padding
			var $d = $("td:eq(2) div", this);
			$d.css("padding-left", (level * 18 + 5) + "px");
			
			// set parent node
			$(this).attr("isEdit", "Y").attr("parentId", $pTr.attr("id"));
		});
		
		if(!$("#saveBtn").attr("disabled") || $("#saveBtn").attr("disabled") == "disabled")  $("#saveBtn").attr("disabled", false);
	},
	
	color: function(color) {
		var $s = this, tab = $s.element, $trs = $s.getRow();
		if($trs.size() == 0)  return;
		
		$("tr", tab).removeClass("tr-selected");
		$trs.attr("isEdit", "Y").css("background-color", color).attr("color", color);
		
		if(!$("#saveBtn").attr("disabled") || $("#saveBtn").attr("disabled") == "disabled")  $("#saveBtn").attr("disabled", false);
	},
	
	resetSn: function() {
		var $s = this, tab = $s.element;
		
		$("tr:gt(0):visible", tab).each(function(i) {
			$("td:eq(0)", $(this)).text(parseInt(i) + 1);
		});
	},
	
	_initEditInput: function() {
		var $s = this, tab = $s.element;
		
		// init text input
		$s.text_input = $("<input type='text' class='hide' style='height: 29px;margin-left: -5px;' />");
		tab.append($s.text_input);
		
		$s.text_input.bind("click", function(e) { e.stopPropagation(); });
	},
	
	_initTdClick: function($td) {
		var $s = this, tab = $s.element;
		
		$s._blurInput(false);
		
		var $d = $("div", $td).hide(), index = $td[0].cellIndex, $input;
		
		$td.append($s.text_input.width($td.width() + 6).val($d.text()).show());
		$s.text_input.click().focus();
	},
	
	_blurInput: function(isBody) {
		var $s = this, tab = $s.element, $input = $s.text_input, $d;
		
		if($input && $input.is(":visible"))  $d = $input.prev();
		if(!$input || $input.size() == 0 || !$d || $d.size() == 0)  return;
		
		// get origin display text and input value
		$input.hide();
		var origin = $d.text();
		var value = $input.val();
		
		// init edit value to display when input blur
		$d.text(value).show();
		
		if(isBody)  tab.append($input);
		
		// enable save button and set edit status to td
		if(!$("#saveBtn").attr("disabled") || $("#saveBtn").attr("disabled") == "disabled")  $("#saveBtn").attr("disabled", false);
		
		if(origin.trim() != value.trim()) {
			$d.parent().attr("isEdit", "Y");
			$d.closest("tr").attr("isEdit", "Y");
		}
	},
	
	_initFirstTdBorder: function() {
		var $s = this, tab = $s.element;
		
		$("tr:eq(0) th:eq(0)", tab).css("border-left", "0");
		
		$("tr:gt(0)", tab).each(function() {
			$("td:eq(0)", $(this)).css("border-left", "0");
		});
	},
	
	_initClickEvent: function() {
		var $s = this, tab = $s.element;
		
		$("tr:gt(0)", tab).click(function(e) {
			$("tr", tab).removeClass("tr-selected");
			$(this).addClass("tr-selected");
			
			if($(this).attr("isNode") == "Y")  e.stopPropagation();
		});
		
		$("tr[isNode='Y']", tab).each(function() {
			$("td:eq(2)", $(this)).bind("click", function() { $s._initTdClick($(this)); });
		});
	},
	
	_initContextMenu: function() {
		var $s = this, tab = $s.element;
		
		if(!$s.options.menu)  return;
		
		$("tr:gt(0)", tab).bind("contextmenu", function(e) {
			$s._blurInput(true);
			
			// show menu
			$("#" + $s.options.menu).omMenu("show", e);
			
			// select row
			$("tr", tab).removeClass("tr-selected");
			$(this).addClass("tr-selected");
		});
	},
	
	_mouseCapture: function(event) {
		
		return true;
	},
	
	_mouseStart: function(event) {
		var $s = this, tab = $s.element;
		
		// init drag type, if is drag row for sort or drag for multi select
		$s.DRAGTYPE = event.target.cellIndex == 0 ? $s.drag.row_sort : $s.drag.multi_select; 
		
		if($s.DRAGTYPE == $s.drag.multi_select) {
			$("tr", tab).removeClass("tr-selected");
			
			$s._blurInput(true);
			$s.startPos = {x: event.clientX, y: event.clientY};
			
			$s.line_area.css({"left": event.clientX + "px", "top": event.clientY + "px"}).show();
		}
		else {
			if($("tr.tr-selected", tab).size() == 0) {
				var $tr = $(event.target).closest("tr");
				if($tr.size() > 0)  $tr.click();
			}
				
			$s.line_area.height(0).css("left", 0).show();
		}
	},
	
	_mouseDrag: function(event) {
		var $s = this, tab = $s.element;
		
		if($s.DRAGTYPE == $s.drag.multi_select) {
			var sp = $s.startPos, ep = {x: event.clientX, y: event.clientY};
			$s.endPos = ep;
			
			var x = sp.x < ep.x ? sp.x : ep.x, y = sp.y < ep.y ? sp.y : ep.y;
			var w = Math.abs(sp.x - ep.x), h = Math.abs(sp.y - ep.y);
			
			$s.line_area.css({"left": x + "px", "top": y + "px"}).width(w).height(h);
		}
		else {
			var w = tab.width(), $tr = $(event.target).closest("tr");
			
			if($tr.size() > 0) {
				var t = $tr.offset().top + 29;
				$s.line_area.width(w - 2).css("top", t);
			}
		}
	},
	
	_mouseStop: function(evnet) {
		var $s = this, tab = $s.element;
		
		if($s.DRAGTYPE == $s.drag.multi_select) {
			$("tr", tab).removeClass("tr-selected");
			var sy = $s.startPos.y < $s.endPos.y ? $s.startPos.y : $s.endPos.y;
			var ey = $s.startPos.y < $s.endPos.y ? $s.endPos.y : $s.startPos.y;
			
			
			$("tr:gt(0)", tab).each(function() {
				var t1 = $(this).offset().top, t2 = t1 + $(this).height();
				
				if((sy < t1 && t1 < ey) || (sy < t2 && t2 < ey) || (sy > t1 && ey < t2)) {
					$(this).addClass("tr-selected");
				}
			});
		}
		else {
			var $tr = $(event.target).closest("tr"), $dragTr = $("tr.tr-selected", tab);
			
			if($tr.size() > 0 && $dragTr.size() > 0 && $tr[0] !== $dragTr[0]) {
				// move drag row
				$tr.after($dragTr);
				
				// reset drag row name level
				var level = parseInt($tr.attr("level")), isNode = $tr.attr("isNode") == "Y";
				if(isNode)  level += 1;
				
				var $d = $("td:eq(2) div", $dragTr.attr("level", level));
				$d.css("padding-left", (level * 18 + 5) + "px");
				
				// reset drag row parent id
				var $pTr = $dragTr.prevAll("tr[isNode='Y']");
				
				if($pTr.size() > 0) {
					$pTr.each(function() {
						if(parseInt($(this).attr("level")) < level) {
							$dragTr.attr("parentId", $(this).attr("id"));  return false;
						}
					});
				}
				
				// reset sn column
				$s.resetSn();
				
				$dragTr.attr("isEdit", "Y");
				if(!$("#saveBtn").attr("disabled") || $("#saveBtn").attr("disabled") == "disabled")  $("#saveBtn").attr("disabled", false);
			}
		}
		
		$s.line_area.hide();
	}
});	
	
})(jQuery);